package org.fujene.sandbox;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Arrays;
import org.junit.Test;

public class SandBox{
	@Test
	public void byteBufferTest() throws IOException{
		File testFile = new File("TEST");
		if(!testFile.exists()) testFile.createNewFile();
		RandomAccessFile accessor = null;
		byte[] testWriteBytes = {0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b};
		byte[] testReadBytes = new byte[12];
		byte[] testFullBytes = new byte[1048576];
		int iteration = 2000;
		try{
			accessor = new RandomAccessFile(testFile, "rw");
			FileChannel channel = accessor.getChannel();
			ByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 1048576);

			long[] totaltime = {0, 0};
			for(int k = 0; k < 100; k++){
				long time = System.nanoTime();
				// Make random access
				for(int i = 0; i < iteration; i++){
					int randombyteA = (int)(Math.random() % 1048564);
					int randombyteB = (int)(Math.random() % 1048564);
					buffer.position(randombyteA);
					buffer.put(testWriteBytes);
					buffer.position(randombyteB);
					buffer.get(testReadBytes);
					if(!Arrays.equals(testWriteBytes, testReadBytes))
						throw new IOException("Buffering failed.");
				}
				time = System.nanoTime() - time;
				totaltime[0] += time;
				System.out.println(iteration + " repetition: " + (time / 1000.0 / 1000.0) + "ms.");

				channel.close();

				time = System.nanoTime();
				// Make random access
				for(int i = 0; i < iteration; i++){
					int randombyteA = (int)(Math.random() % 1048564);
					int randombyteB = (int)(Math.random() % 1048564);
					for(int j = 0; j < 12; j++)
						testFullBytes[randombyteA + j] = testWriteBytes[j];
					for(int j = 0; j < 12; j++)
						testReadBytes[j] = testFullBytes[randombyteB + j];

					if(!Arrays.equals(testWriteBytes, testReadBytes))
						throw new IOException("Buffering failed.");
				}
				time = System.nanoTime() - time;
				totaltime[1] += time;
				System.out.println(iteration + " repetition: " + (time / 1000.0 / 1000.0) + "ms.");
			}
			System.out.println("mmap: " + iteration + " repetition: " + (totaltime[0] / 1000.0 / 1000.0 / 100.0) + "ms.");
			System.out.println("array: " + iteration + " repetition: " + (totaltime[1] / 1000.0 / 1000.0 / 100.0) + "ms.");
		}finally{
			if(accessor != null) accessor.close();
		}

		testFile.delete();
	}
}
